package com.example.demogateway.config;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
import org.springframework.cloud.gateway.support.BodyInserterContext;
import org.springframework.cloud.gateway.support.DefaultServerRequest;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Base64;
import java.util.Map;
import java.util.Set;

/**
 * 请求参数统一处理
 */
@Component
public class MvcFilter implements GlobalFilter, Ordered {
    Logger logger = LoggerFactory.getLogger(MvcFilter.class);

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String string=new String("fdfdfd/login");
        if(string.endsWith("/login")){

        }
       /* ServerHttpRequest serverHttpRequest = exchange.getRequest();
        String path = serverHttpRequest.getPath().toString();
        boolean flag = serverHttpRequest.getPath().toString().contains("/login");
        if (!flag) {
            String token = serverHttpRequest.getHeaders().getFirst("token");
            *//**
             * 校验是否登录 未登录 返回401
             *//*
            ServerHttpResponse response = exchange.getResponse();
            if (!StringUtils.hasLength(token)) {
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            //redis异常暂时屏蔽
            *//*if (!redisTemplate.hasKey(token)) {
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }*//*
        }
        String method = serverHttpRequest.getMethodValue();
        MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
        ServerRequest serverRequest = new DefaultServerRequest(exchange);
        if ("POST".equals(method)) {
            if (flag) {
                return chain.filter(exchange);
            }
            Mono<String> mono = serverRequest.bodyToMono(String.class);
            Mono<String> modifiedBody = Mono.empty();
            if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) {
                logger.info(path + ":" + "post 请求");
                modifiedBody = serverRequest.bodyToMono(String.class).flatMap(body -> {
                    //获取POST原始参数
                    JSONObject jsonObject = JSONObject.parseObject(body);
                    logger.info("process befor :{}", jsonObject.toJSONString());
                    String datastr = jsonObject.get("data").toString();
                    jsonObject.put("data", new String(Base64.getDecoder().decode(datastr)));
                    logger.info("process after:{}", jsonObject.toJSONString());
                    //处理完成后重新放回
                    return Mono.just(jsonObject.toJSONString());
                });
            } else {
                logger.info(path + ":" + "post 上传");
                return chain.filter(exchange);
            }
            BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
            HttpHeaders headers = new HttpHeaders();
            headers.putAll(exchange.getRequest().getHeaders());
            headers.remove(HttpHeaders.CONTENT_LENGTH);
            CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
            return processResp(exchange, chain, bodyInserter, headers, outputMessage);
        } else if ("GET".equals(method)) {
            logger.info(path + ":" + "get 请求");
            Map requestQueryParams = serverHttpRequest.getQueryParams();
            Map<String, String> map = ((MultiValueMap) requestQueryParams).toSingleValueMap();
            Set<String> set = map.keySet();
            for (String o : set) {
                logger.info(o + ":" + map.get(o).toString());
            }
            String token = exchange.getRequest().getHeaders().getFirst("token");
            logger.info("token:" + token);
            return chain.filter(exchange);
        }*/
        return chain.filter(exchange);
    }

    private Mono processResp(ServerWebExchange exchange, GatewayFilterChain chain, BodyInserter bodyInserter, HttpHeaders headers, CachedBodyOutputMessage outputMessage) {
        return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
            ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
                @Override
                public HttpHeaders getHeaders() {
                    long contentLength = headers.getContentLength();
                    HttpHeaders httpHeaders = new HttpHeaders();
                    httpHeaders.putAll(super.getHeaders());
                    if (contentLength > 0) {
                        httpHeaders.setContentLength(contentLength);
                    } else {
                        httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
                    }
                    return httpHeaders;
                }

                @Override
                public Flux<DataBuffer> getBody() {
                    return outputMessage.getBody();
                }
            };
            return chain.filter(exchange.mutate().request(decorator).build());
        }));
    }


    /**
     * 设置过滤器的启动顺序 数字越小越先执行
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }


    public static void main(String[] args) {
        String string=new String("fdfdfd/login1");
        if(string.endsWith("/login")){
            System.out.println("登录地址");
        }else{
            System.out.println("非登录地址");
        }
    }
}
